package com.truyen.controller;

import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.Random;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import nl.captcha.Captcha;

import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.truyen.model.UploadItem;
import com.truyen.model.AuthInfo;
import com.truyen.persistence.entity.Account;
import com.truyen.persistence.entity.UserLiked;
import com.truyen.persistence.entity.BookmarkChapter;
import com.truyen.service.BookmarkChapterService;
import com.truyen.service.MailService;
import com.truyen.service.UserService;
import com.truyen.service.UserLikedService;
import com.truyen.utils.DateTimeUtils;
import com.truyen.utils.PagingInfo;
import com.truyen.utils.PicasawebAlbumUtil;

@Controller
@RequestMapping("/thanh-vien")
public class UserController {
	
	@Autowired
	@Qualifier("userDetailService")
	private UserService userService;
	
	@Autowired
	private UserLikedService userLikedService;
	
	@Autowired
	private BookmarkChapterService bookmarkChapterService;
	
	@Autowired
	private MailService mailService;
	
	@Autowired
	private Md5PasswordEncoder md5PasswordEncoder;
	
	
	@RequestMapping("/redirect.htm")
	@PreAuthorize("hasRole('ROLE_USER')")
	public String redirectAllowRole(){
		Account account = userService.getCurrentLoggedInUser();
		switch (account.getLevel()) {
	        case 3:
	        	return "redirect:/admin/main.htm";
	        default:
	        	return "redirect:/account/login.htm";
	    }
	}
	
	//kiem tra dang nhap bang ajax
	@RequestMapping("/authenticate.htm")
	public @ResponseBody boolean authenticate(@ModelAttribute AuthInfo authInf) {
		return userService.authenticate(authInf.getUserName(), 
				authInf.getPwd());
	}
	
	//dang nhap sau khi dang ky
	public boolean login(String email, String pwd){
		return userService.authenticate(email,pwd);
	}
	
	//dang ky thanh vien
	@RequestMapping("/dang-ky.htm")
	public String register(Model model){
		return "/user/register/register";
	}
	
	//xu ly dang ky thanh vien
	@RequestMapping("/xu-ly-dang-ky.htm")
	public String processCreateNewAccount(Model model,HttpServletRequest request,
			@RequestParam(defaultValue = "") String email,
			@RequestParam(defaultValue = "") String pwd,
			@RequestParam(defaultValue = "") String nickName,
			@RequestParam(defaultValue = "") String answer) throws Exception {
		if (email != null && !email.equals("") && pwd != null
				&& !pwd.equals("") && nickName != null && !nickName.equals("")){
			Captcha captcha = (Captcha) request.getSession().getAttribute("Captcha5");
			request.setCharacterEncoding("UTF-8"); // Do this so we can capture non-Latin chars
			if (captcha.isCorrect(answer)) {
				Account account = userService.findItemByProperty("email",email);
				if(account == null){
					account = userService.findItemByProperty("nickName", nickName);
					if(account == null){
						Date dayReg = new Date();
						boolean isActive = true;
						int level = 2;
						String avatar = "http://4.bp.blogspot.com/-49JcqMXrClA/UFTSKKEwmRI/AAAAAAAAAPQ/Bim-43ADo3g";
						account = new Account(email,md5PasswordEncoder.encodePassword(pwd, null),nickName,level,dayReg,isActive,avatar);
						userService.save(account);
						boolean flagLogin = login(email,pwd);
						if(flagLogin){
							return "redirect:/thanh-vien/chinh-sua-avatar.htm";
						}else{
							return "redirect:/thanh-vien/dang-ky.htm";
						}
						
					}else{
						model.addAttribute("notice", "Nick name này đã được sử dụng");
						model.addAttribute("email", email);
						model.addAttribute("pwd", pwd);
						model.addAttribute("nickName", nickName);
						return "/user/register/register";
					}
				}else{
					model.addAttribute("notice", "Email này đã được đăng ký");
					model.addAttribute("email", email);
					model.addAttribute("pwd", pwd);
					model.addAttribute("nickName", nickName);
					return "/user/register/register";
				}
			} else {
				model.addAttribute("notice", "Sai captcha!");
				model.addAttribute("email", email);
				model.addAttribute("pwd", pwd);
				model.addAttribute("nickName", nickName);
				return "/user/register/register";
			}
		}else{
			return "redirect:/thanh-vien/dang-ky.htm";
		}
	}
	
	//dang ky thanh vien
	@RequestMapping("/quen-mat-khau.htm")
	public String forgerPassword(Model model){
		return "/user/forgetPassword/forgetPassword";
	}
	
	//xu ly dang ky thanh vien
	@RequestMapping("/xu-ly-quen-mat-khau.htm")
	public String processCreateNewAccount(Model model,HttpServletRequest request,
			@RequestParam(defaultValue = "") String email,
			@RequestParam(defaultValue = "") String answer) throws Exception {
		String notice = "";
		if (email != null && !email.equals("")){
			Captcha captcha = (Captcha) request.getSession().getAttribute("Captcha5");
			request.setCharacterEncoding("UTF-8"); // Do this so we can capture non-Latin chars
			if (captcha.isCorrect(answer)) {
				Account account = userService.findItemByProperty("email", email);
				if(account != null){
					String randomPwd = "";
					String data1 = "123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
					int chieudaiDT = data1.length();
					int chieudai = 6;
					for (int j = 0; j < chieudai; j++) {
						randomPwd += data1.charAt(new Random().nextInt(chieudaiDT));
					}
					String subject = "QUÊN MẬT KHẨU TỪ TRUYENZ.COM";
					String content = "Bạn hoặc ai đó đã sử dụng chức năng quên mật khẩu từ http://truyenz.com/.\n\n";
					content += "Mật khẩu mới của bạn là : "+randomPwd+"\n\n";
					content += "Hãy đăng nhập với mật khẩu mới của bạn";
					mailService.sendNotify(subject, content, email);
					String newPassword = md5PasswordEncoder.encodePassword(randomPwd, null);
					userService.updateColumnString(account.getId(),"pwd",newPassword);
					return "redirect:/truyen-tranh/trang-chu.htm";
				}else{
					notice ="Email "+email+" không tồn tại trong hệ thống.";
					model.addAttribute("notice", notice);
					return "/user/forgetPassword/forgetPassword";
				}
			} else {
				model.addAttribute("notice", "Sai captcha!");
				model.addAttribute("email", email);
				return "/user/forgetPassword/forgetPassword";
			}
		}else{
			notice ="Giá trị nhập vào không hợp lệ!";
			model.addAttribute("notice", notice);
			return "/user/forgetPassword/forgetPassword";
		}
	}
	
	//danh sach truyen yeu thich
	@PreAuthorize("hasAnyRole('ROLE_USER')")
	@RequestMapping("/danh-sach-truyen-yeu-thich-trang-{curPage}.htm")
	public String userLiked(Model model,@PathVariable("curPage") int curPage){
		if(curPage > 0){
			PagingInfo pInfo = new PagingInfo();
			pInfo.setCurrentPage(curPage);
			pInfo.setSizePerPage(10);
			Account account = userService.getCurrentLoggedInUser();
			List<UserLiked> lstItem = userLikedService.getLstByAccountWithPaging(account,pInfo);
			model.addAttribute("lstItem", lstItem);
			model.addAttribute("pInfo", pInfo);
			return "/user/userLiked/index";
		}else{
			return "redirect:/truyen-tranh/trang-chu.htm";
		}
	}
	
	//danh sach truyen yeu thich
	@PreAuthorize("hasAnyRole('ROLE_USER')")
	@RequestMapping("/danh-sach-chapter-dang-xem-trang-{curPage}.htm")
	public String userBookmark(Model model,@PathVariable("curPage") int curPage){
		if(curPage > 0){
			PagingInfo pInfo = new PagingInfo();
			pInfo.setCurrentPage(curPage);
			pInfo.setSizePerPage(10);
			Account account = userService.getCurrentLoggedInUser();
			List<BookmarkChapter> lstItem = bookmarkChapterService.getLstByAccountWithPaging(account,pInfo);
			model.addAttribute("lstItem", lstItem);
			model.addAttribute("pInfo", pInfo);
			return "/user/userBookmark/index";
		}else{
			return "redirect:/truyen-tranh/trang-chu.htm";
		}
	}
	
	//quan ly tai khoan cua thanh vien
	@RequestMapping("/thong-tin-ca-nhan.htm")
	@PreAuthorize("hasAnyRole('ROLE_USER')")
	public String manageUser(Model model){
		return "/user/userInfo/index";
	}
	
	// xu ly edit account
	@RequestMapping("/xu-ly-cap-nhat-thong-tin.htm")
	public String processEditAccount(Model model,@RequestParam Long id,
			@RequestParam(defaultValue = "") String fullName,
			@RequestParam(defaultValue = "") String address,
			@RequestParam(defaultValue = "") String mobile,
			@RequestParam(defaultValue = "true") boolean sex,
			@RequestParam(defaultValue = "") String birthDay) {
		if(id != null && id > 0){
			Date birthD = DateTimeUtils.StringDateToDate(birthDay);
			boolean flag = userService.updateAccountInfo(id,fullName,address,mobile,sex,birthD);
			if(flag){
				model.addAttribute("notice", "Cập nhật thành công!");
			}else{
				model.addAttribute("notice", "Cập nhật thất bại!");
			}
		}else{
			model.addAttribute("notice", "Giá trị điền vào không hợp lệ!");
		}
		return "/user/userInfo/index";
	}
	
	//thay doi mat khau hien tai
	@RequestMapping("/thay-doi-mat-khau.htm")
	@PreAuthorize("hasAnyRole('ROLE_USER')")
	public String changePwd(Model model){
		return "/user/changePwd/index";
	}
	
	// xu ly thay doi mat khau hien tai
	@RequestMapping("/xu-ly-thay-doi-mat-khau.htm")
	public String processChangePwd(Model model,@RequestParam Long id,
			@RequestParam String pwdCur,
			@RequestParam String pwd) {
		if(id != null && id > 0 && pwdCur != null && !pwdCur.equals("") && pwd != null && !pwd.equals("") ){
			Account account = userService.findById(id);
			if(account != null){
				pwdCur = md5PasswordEncoder.encodePassword(pwdCur, null);
				if(pwdCur.equals(account.getPwd())){
					boolean flag = userService.updatePwdAccount(id,md5PasswordEncoder.encodePassword(pwd, null));
					if(flag){
						model.addAttribute("notice", "Cập nhật thành công!");
					}else{
						model.addAttribute("notice", "Cập nhật thất bại!");
					}
				}else{
					model.addAttribute("notice", "Mật khâu hiện tại ko chính xác.");
				}
			}else{
				model.addAttribute("notice", "Giá trị điền vào không hợp lệ.");
			}
		}else{
			model.addAttribute("notice", "Giá trị điền vào không hợp lệ.");
		}
		return "/user/changePwd/index";
	}
	
	//chinh sua avatar
	@RequestMapping("/chinh-sua-avatar.htm")
	@PreAuthorize("hasAnyRole('ROLE_USER')")
	public String changeAvatar(Model model){
		return "/user/changeAvatar/index";
	}

	// xu ly thay doi mat khau hien tai
	@RequestMapping("/xu-ly-chinh-sua-avatar.htm")
	public String processChangeAvatar(Model model,@RequestParam Long id,
			@ModelAttribute UploadItem uploadItem,
			@RequestParam(defaultValue="") String avatar) throws Exception {
		if(id != null && id > 0 ){
			Account account = userService.findById(id);
			if(account != null){
				InputStream inputStream = null;
				if(avatar==null || avatar.equals("")){
					MultipartFile uploadedFile = uploadItem.getFileData();
					inputStream = uploadedFile.getInputStream();
				}else {
					avatar = avatar.replace(" ", "%20");
					URL fileURL = new URL(avatar);
					URLConnection urlConn = fileURL.openConnection();
				    urlConn.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1");
					inputStream = urlConn.getInputStream();
				}
				byte[] imageBytes = IOUtils.toByteArray(inputStream);
				String urlAvatar = PicasawebAlbumUtil.uploadImageFromUrl(imageBytes);
				if(urlAvatar.equals("")){
					model.addAttribute("notice", "Cập nhật thất bại.");
				}else{
					userService.updateColumnString(id, "avatar", urlAvatar);
					model.addAttribute("notice", "Cập nhật thành công");
				}
			}else{
				model.addAttribute("notice", "Giá trị điền vào không hợp lệ.");
			}
		}else{
			model.addAttribute("notice", "Giá trị điền vào không hợp lệ.");
		}
		return "/user/changeAvatar/index";
	}
}
